package com.sikulifang.bank.simulation.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;
import com.sikulifang.bank.simulation.persistence.Bank;
import com.sikulifang.frequency.core.FrequencyContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * ClassName MessageService
 * Description 银行报文统一入口
 *
 * @author Yat
 * Date 2023/5/30 14:21
 * version 1.0
 */
@Slf4j
@Service
public class MessageService {


    private IBankService bankService;
    private List<IBankMessage> accountServices;

    /**
     * Description: 处理报文
     * <p>
     * Date: 2023/5/30 14:27
     *
     * @param bank    银行对象
     * @param message 报文
     * @return {@link Object}
     */
    public byte[] handleMessage(Bank bank, String message) {

        Entity entity = bankService.get(bank.getId());
        bank = entity.toBean(Bank.class);

        String code = bank.getCode();
        String charset = bank.getCharset();
        // String charset = "UTF-8";

        IBankMessage accountService = getAccountService(code);
        if (null == accountService) {
            log.error("------------银行code错误------------");
            return StrUtil.bytes("接口异常", charset);
        }

        String type = accountService.getActionType(message);
        FrequencyContext.setType(code, type);
        try {
            FrequencyContext.acquire();
            log.info("接口类型：'{}'", type);

            String inlet = accountService.inlet(message.trim());
            if (StrUtil.isBlank(inlet)) {
                inlet = "系统异常";
            }
            return StrUtil.bytes(inlet, charset);
        } catch (InterruptedException e) {
            String access = accountService.prohibitAccess("接口类型：'{" + type + "}'调用频率过快");
            return StrUtil.bytes(access, charset);
        } finally {
            FrequencyContext.release(Boolean.TRUE);
        }
    }


    private IBankMessage getAccountService(String code) {
        for (IBankMessage accountService : accountServices) {
            if (code.equals(accountService.bankCode())) {
                return accountService;
            }
        }
        return null;
    }

    @Autowired
    public void setBankService(IBankService bankService) {
        this.bankService = bankService;
    }

    @Autowired
    public void setAccountServices(List<IBankMessage> accountServices) {
        this.accountServices = accountServices;
    }
}
